package com.example.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.example.demo.dto.*;
import com.example.demo.entity.*;
import com.example.demo.mapper.ReciteMapper;
import com.example.demo.mapper.ReciteRecordMapper;
import com.example.demo.param.ReciteData;
import com.example.demo.param.ReciteParam;
import com.example.demo.service.ReciteService;
import com.example.demo.utils.TimeUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class ReciteServiceImpl implements ReciteService {

    @Resource
    private ReciteMapper reciteMapper;

    @Resource
    private ReciteRecordMapper reciteRecordMapper;

    @Resource
    private RedisTemplate<String, Integer> redisTemplate;

    @Override
    public ReciteDTO getReciteCount(ReciteParam reciteParam) {
        //从redis中取数
        Long userId = reciteParam.getUserId();
        Integer authorId = reciteParam.getAuthorId();
        Integer preAuthorId = redisTemplate.opsForValue().get(String.valueOf(userId));
        if(authorId==null&&preAuthorId==null){
            /*如果没有诗集的话，默认给他一个苏轼第一首诗*/
            Recite recite = new Recite(userId,1,2180,0);
            reciteMapper.insert(recite);
            Poetry poetry = reciteMapper.selectPoetryByReciteCount(1, 0);
            redisTemplate.opsForValue().set(String.valueOf(userId),1);
            return new ReciteDTO(poetry,2180,0);
        }else if(authorId==null){
            QueryWrapper<Recite> queryWrapper = new QueryWrapper<Recite>();
            queryWrapper.eq("user_id",userId).eq("author_id",preAuthorId);
            Recite recite = reciteMapper.selectOne(queryWrapper);
            Integer nowCount = recite.getNowCount();
            Poetry poetry = reciteMapper.selectPoetryByReciteCount(preAuthorId,nowCount);
            return new ReciteDTO(poetry,recite.getTotalCount(),nowCount);
        }else {
            Map<String, Object> map = new HashMap<>();
            map.put("user_id",userId);
            map.put("author_id",authorId);
            List<Recite> reciteList =  reciteMapper.selectByMap(map);
            /*选了一个从没有背过的诗集*/
            if (reciteList.size()==0){
                /*获取某个诗人诗集的总数量*/
                int count = reciteMapper.selectCountByAuthorId(authorId);
                reciteMapper.insert(new Recite(userId,authorId,count,0));
                redisTemplate.opsForValue().set(String.valueOf(userId),authorId);
                Poetry poetry = reciteMapper.selectPoetryByReciteCount(authorId, 0);
                return new ReciteDTO(poetry,count,0);
            }else {
                Poetry poetry = reciteMapper.selectPoetryByReciteCount(authorId, reciteList.get(0).getNowCount());
                redisTemplate.opsForValue().set(String.valueOf(userId),authorId);
                return new ReciteDTO(poetry,reciteList.get(0).getTotalCount(),reciteList.get(0).getNowCount());
            }
        }
    }

    @Override
    public Poetry getNextPoetry(Integer authorId, Integer count) {
        return reciteMapper.selectPoetryByReciteCount(authorId,count);
    }

    @Override
    public void addReciteData(ReciteData reciteData) {
        Integer preCount = reciteData.getPreCount();
        Integer addCount = reciteData.getAddCount();
        Long spendTime = reciteData.getSpendTime();
        Long userId = reciteData.getUserId();
        Integer authorId = reciteData.getAuthorId();
        /*结束背诗 更新背诗时间*/
        UpdateWrapper<Recite> updateWrapper = new UpdateWrapper<Recite>();
        updateWrapper.eq("user_id",userId).eq("author_id",authorId);
        reciteMapper.update(new Recite(preCount+addCount),updateWrapper);
        /*结束背诗 插入背诗时间*/
        reciteRecordMapper.insert(new ReciteRecord(userId,authorId,spendTime,addCount));
    }

    @Override
    public ReciteDashboardDTO getReciteDashBoard(Long userId) {
        ReciteRecordDo today = reciteRecordMapper.selectTodayCount(userId);
        ReciteRecordDo week = reciteRecordMapper.selectByUserId(userId,7);
        ReciteRecordDo month = reciteRecordMapper.selectByUserId(userId,30);
        ReciteDashboardDTO result = new ReciteDashboardDTO();
        result.setTodayTime(TimeUtil.formatSeconds(today.getSpendTime()));
        result.setTodayCount(today.getReciteCount());
        result.setWeekCount(week.getReciteCount());
        result.setMonthCount(month.getReciteCount());
        result.setWeekTime(TimeUtil.formatSeconds(week.getSpendTime()));
        result.setMonthTime(TimeUtil.formatSeconds(month.getSpendTime()));
        return result;
    }

    @Override
    public ReciteTimeDTO getReciteTimeCount() {
        List<ReciteTime> list = reciteRecordMapper.selectReciteTime();
        List<ReciteTime> collect = list.stream().sorted(Comparator.comparing(ReciteTime::getSpendTime).reversed())
                .collect(Collectors.toList());
        int size = collect.size();
        String[] usernameArray = new String[size];
        Long[] reciteTimeArray = new Long[size];
        for (int i = 0; i < size; i++) {
            usernameArray[i] = collect.get(i).getUsername();
            reciteTimeArray[i] = collect.get(i).getSpendTime()/60;
        }
        return new ReciteTimeDTO(usernameArray,reciteTimeArray);
    }

    @Override
    public ReciteNumDTO getReciteNumRank() {
        List<ReciteNum> list = reciteRecordMapper.selectReciteNum();
        List<ReciteNum> collect = list.stream().sorted(Comparator.comparing(ReciteNum::getReciteNum).reversed())
                .collect(Collectors.toList());
        int size = collect.size();
        String[] usernameArray = new String[size];
        Integer[] reciteNumArray = new Integer[size];
        for (int i = 0; i < size; i++) {
            usernameArray[i] = collect.get(i).getUsername();
            reciteNumArray[i] = collect.get(i).getReciteNum();
        }
        return new ReciteNumDTO(usernameArray,reciteNumArray);
    }
}
